package cn.wolfcode.shop.util;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import cn.wolfcode.shop.domain.UserLogin;
import cn.wolfcode.shop.exception.CodeMsg;
import cn.wolfcode.shop.exception.GlobalException;

// 自定义过滤规则
@Component
public class UserLoginArgumentResolver implements HandlerMethodArgumentResolver {

	@Autowired
	private RedisTemplate redisTemplate;

	/**
	 * 所有的controller都会进入这个方法
	 * 判断controller方法参数中,是否有需要自定义解析的参数,如果有返回true
	 * 如果返回true则springmMVC会调用resolveArgument方法,具体进行参数解析,否则不会调用
	 */
	@Override
	public boolean supportsParameter(MethodParameter parameter) {
		Class<?> parameterType = parameter.getParameterType();
		// 如果controller有我们需要的类型
		if (parameterType == UserLogin.class) {
			// 返回true回去调用resolveArgument
			return true;
		}
		return false;
	}

	/**
	 * 具体做参数解析
	 */
	@Override
	public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
			NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
		HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest();
		String token = request.getHeader("head_token");
		// 1.判断token的有效性
		if (!StringUtils.hasLength(token)) {
			// 2 如果token非法抛出异常
			throw new GlobalException(CodeMsg.USER_TOKEN_ERROR);
		} else {
			// 3 没问题就通过token获取登录用户
			UserLogin userLogin = (UserLogin) redisTemplate.opsForValue()
					.get(RedisConstance.USER_CURRENT.replace("TOKEN", token));
			// 4 如果当前登录用户为null,就提示用户登录超时,重新登录
			if (userLogin == null) {
				throw new GlobalException(CodeMsg.USER_TIME_OUT);
			}
			return userLogin;
		}
	}

}
